package com.csaba.swing.gui.login;

import java.awt.Component;

import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JSeparator;

import com.csaba.connector.BankServiceFactory;
import com.csaba.connector.ServiceException;
import com.csaba.connector.model.Bank;
import com.csaba.swing.MainWindow;
import com.csaba.swing.gui.wizard.WizardContext;
import com.csaba.swing.gui.wizard.WizardPage;
import com.csaba.util.encryption.EncryptedStore;

@SuppressWarnings( "serial" )
public class BankSelectPage extends WizardPage
{
	private JRadioButton bankRadio;
	private JComboBox bankCombo;
	private JCheckBox saveDetails;
	private JRadioButton storedCustomersRadio;
	private JComboBox storedCustomersCombo;

	private ButtonGroup group;

	private boolean ready = false;

	@Override
	public void init( final WizardContext context )
	{
		super.init(context);

		//TODO implement "login with all saved customers" option

		//create input fields
		add(new JLabel(MainWindow.getString("BankSelectPage.loginWith"))); //$NON-NLS-1$
		add(new JSeparator());

		add(storedCustomersRadio = new JRadioButton(MainWindow.getString("BankSelectPage.storedCustomer"))); //$NON-NLS-1$
		add(storedCustomersCombo = new JComboBox(LoginDetails.loadAll()));

		add(bankRadio = new JRadioButton(MainWindow.getString("BankSelectPage.newCustomer"))); //$NON-NLS-1$
		try
		{
			final Bank[] banks = BankServiceFactory.getAvailableBanks();
			add(bankCombo = new JComboBox(banks));
		}
		catch ( final ServiceException e )
		{
			throw new IllegalStateException("Failed to create view.", e);
		}

		add(new JSeparator());
		add(saveDetails = new JCheckBox(MainWindow.getString("BankSelectPage.saveDetails"))); //$NON-NLS-1$

		group = new ButtonGroup();
		group.add(bankRadio);
		group.add(storedCustomersRadio);

		addChangeListener(bankCombo);
		addChangeListener(bankRadio);
		addChangeListener(storedCustomersCombo);
		addChangeListener(storedCustomersRadio);
		addChangeListener(saveDetails);

		if ( storedCustomersCombo.getItemCount() < 1 )
		{
			storedCustomersRadio.setEnabled(false);
			storedCustomersCombo.setEnabled(false);
			bankRadio.setSelected(true);
		}
		else
		{
			storedCustomersRadio.setSelected(true);
			storedCustomersCombo.setSelectedItem(null);
		}
	}

	@Override
	public boolean leave( final int action )
	{

		if ( action == ACTION_NEXT )
		{
			if ( !ready )
			{
				JOptionPane.showMessageDialog(context.getDialog().getOwner(), context.getDialog().getMessage(),
						MainWindow.getString("BankSelectPage.titleWarning"), JOptionPane.WARNING_MESSAGE); //$NON-NLS-1$
				return false;
			}
			if ( bankRadio.isSelected() )
			{
				final Bank bank = (Bank) bankCombo.getSelectedItem();
				final boolean saveDetails = this.saveDetails.isSelected();

				( (LoginWizardModel) context.getWizardModel() ).setBank(bank);
				( (LoginWizardModel) context.getWizardModel() ).setSaveDetails(saveDetails);
			}
			else if ( storedCustomersRadio.isSelected() )
			{
				final LoginDetails details = (LoginDetails) storedCustomersCombo.getSelectedItem();

				Bank selected = null;
				try
				{
					final Bank[] banks = BankServiceFactory.getAvailableBanks();
					for ( final Bank bank : banks )
					{
						if ( bank.getName().equals(details.getBankCode()) )
						{
							selected = bank;
							break;
						}
					}
				}
				catch ( final ServiceException e )
				{
					throw new IllegalStateException("Cannot get list of banks.", e);
				}

				( (LoginWizardModel) context.getWizardModel() ).setBank(selected);
				( (LoginWizardModel) context.getWizardModel() ).setSaveDetails(true);
				context.setProperty(AbstractLoginPage.CP_SAVED_DETAILS, details);
			}
		}

		return true;
	}

	@Override
	protected void updateMessage( final Component component )
	{
		super.updateMessage(component);

		boolean goNext = false;

		//update field status
		if ( bankCombo.equals(component) )
		{
			bankRadio.setSelected(true);
			goNext = true;
		}
		else if ( storedCustomersCombo.equals(component) )
		{
			storedCustomersRadio.setSelected(true);
			goNext = true;
		}

		if ( bankRadio.isSelected() )
		{

			final Bank bank = (Bank) bankCombo.getSelectedItem();
			if ( bank == null )
			{
				context.getDialog().setWarning(MainWindow.getString("BankSelectPage.msg.selectBank")); //$NON-NLS-1$
				ready = false;
				return;
			}

			final boolean saveDetails = this.saveDetails.isSelected();
			if ( saveDetails && !EncryptedStore.getInstance().isOpen() )
			{
				context.getDialog().setWarning(MainWindow.getString("BankSelectPage.msg.setPassword")); //$NON-NLS-1$
				ready = false;
				return;
			}
		}
		else if ( storedCustomersRadio.isSelected() )
		{
			final LoginDetails details = (LoginDetails) storedCustomersCombo.getSelectedItem();
			if ( details == null )
			{
				context.getDialog().setWarning(MainWindow.getString("BankSelectPage.msg.selectCustomer")); //$NON-NLS-1$
				ready = false;
				return;
			}
		}

		ready = true;
		context.getDialog().clearMessage();

		//it is necessary to check whether this is the current page, as sometimes the ItemStateChanged event is dispatched 
		//  twice for JComboBox. In this case this method is processed twice.
		if ( goNext && context.getDialog().getCurrentPage() == this )
		{
			context.getDialog().nextPressed();
		}
	}

	@Override
	public void updateView()
	{
		/*final Bank bank = ( (LoginWizardModel) context.getWizardModel() ).getBank();
		bankCombo.setSelectedItem(bank);*/

		context.getDialog().setReady(false);

		//remove saved details from context, as the customer may decide on entering a new login details
		// instead of using a stored one.
		context.removeProperty(AbstractLoginPage.CP_SAVED_DETAILS);

		super.updateView();
	}
}
